package bintree.leetcode;

import java.util.Deque;
import java.util.LinkedList;

/**
 * 二叉树最大宽度问题
 * @author yuisama
 * @date 2022/02/21 16:40
 **/
public class Num662_BinTreeWidth {
    /**
     * 层序遍历的过程中记录每个节点的编号
     * @param root
     * @return
     */
    public int widthOfBinaryTree(TreeNode root) {
        if (root == null) {
            return 0;
        }
        Deque<TreeNodeWithNum> queue = new LinkedList<>();
        queue.offer(new TreeNodeWithNum(root,1));
        int maxWidth = 0;
        while (!queue.isEmpty()) {
            // 当前层的节点个数
            int size = queue.size();
            // 最开始访问的是当前层最左侧节点
            // 最后访问的是当前层最后侧节点
            // 当前层的宽度就是最后节点编号 - 最开始节点编号 + 1
            int L = 0;
            int R = 0;
            for (int i = 0; i < size; i++) {
                TreeNodeWithNum cur = queue.poll();
                if (i == 0) {
                    // 最左侧节点
                    L = cur.num;
                }
                if (i == size - 1) {
                    R = cur.num;
                }
                if (cur.node.left != null) {
                    queue.offer(new TreeNodeWithNum(cur.node.left, cur.num * 2));
                }
                if (cur.node.right != null) {
                    queue.offer(new TreeNodeWithNum(cur.node.right, cur.num * 2 + 1));
                }
            }
            // 当前层的宽度
            int width = R - L + 1;
            maxWidth = Math.max(maxWidth,width);
        }
        return maxWidth;
    }

    private class TreeNodeWithNum {
        TreeNode node;
        // 节点的编号
        int num;

        public TreeNodeWithNum(TreeNode node, int num) {
            this.node = node;
            this.num = num;
        }
    }
}